#include "Settings.h"
#include <fstream>

Settings::Settings(void)
{
	//m_uint32Values.resize(SETTING_STRINGS_DUMMY);
	//m_stringValues.resize(SETTING_TOTAL_SETTINGS - SETTING_STRINGS_DUMMY);	
	/*Load("settings/setttings.txt");*/
}

Settings::Settings( const std::string& filename )
{
	Load(filename);
}

Settings::Settings( const Settings& settings )
{
	const std::map<std::string,uint32> uint32values = settings.GetRawUint32Values();
	const std::map<std::string,std::string> stringvalues = settings.GetRawStringValues();
	m_uint32Values.clear();
	m_stringValues.clear();

	m_stringValues = stringvalues;
	m_uint32Values = uint32values;
}
Settings::~Settings(void)
{
}

uint32 Settings::GetUint32Value(  const std::string& index ) const
{
	std::map<std::string,uint32>::const_iterator i = m_uint32Values.find(index);
	if(i == m_uint32Values.end()) {
		return 0;
	} else return i->second;
}

std::string Settings::GetStringValue( const std::string& index ) const
{
	std::map<std::string,std::string>::const_iterator i = m_stringValues.find(index);
	if(i == m_stringValues.end()) {
		return "";
	} else return i->second;
}

bool Settings::Load( const std::string& filename )
{

	std::ifstream file;
	file.open(filename.c_str());

	if(!file.is_open()) return false;

	while (!file.eof()) {
		std::string temp;
		std::string temp2;
		file >> temp;
		switch (temp[0])
		{
			case '$':
			{		
				temp = temp.substr(1);
				file >> temp2;
				if(temp2[0] == '=') {
					file >> temp2;
					if(isalpha(temp2[0])) {
						m_stringValues[temp] = temp2;
					} else {
						m_uint32Values[temp] = atoi(temp2.c_str());
					}
				}
			} break;
			case '#':
			{
				std::getline(file,temp); //ignore the comment lines!
			} break;
			default: break;
		} 
	}

	file.close();
	return true;
}

void Settings::SetValue( const std::string& id, const Value& value )
{
	if(!value.size()) {
		sLog.outDebug("Settings::SetValue(): Value doesn't have any parameters!");
		return;
	}
	if(value.size() > 1) {
		sLog.outDebug("Settings::SetValue(): Value has too many parameters! %u", value.size());
		return;
	}
	switch (value.GetType())
	{
		case Value::TYPE_STRING:
		{
			m_stringValues.insert(std::make_pair<std::string,std::string>(id,value));		 
		}	break;
		case Value::TYPE_UINT:
		{
			m_uint32Values.insert(std::make_pair<std::string,uint32>(id,value));
		}	break;
		case Value::TYPE_INT:
		{
			m_uint32Values.insert(std::make_pair<std::string,uint32>(id,value));
		}	break;
		default:
			sLog.outDebug("Settings::SetValue(): Value has unsupported type! %u", value.GetType());
			return;
	}

}

Value Settings::GetValue( const std::string& id ) const
{
	std::map<std::string, uint32>::const_iterator i = m_uint32Values.find(id);

	//it's not a uint32 value
	if(i == m_uint32Values.end()){
		std::map<std::string, std::string>::const_iterator itr = m_stringValues.find(id);
		if(itr == m_stringValues.end()) return Value();//return an empty value
		else return Value(itr->second);
	} else return Value(i->second);

}

void Settings::Save( const std::string& filename )
{
	std::ofstream file;
	file.open(filename.c_str(), std::ios::out);
	if(!file.is_open()) return;
	
	file << "# Uint32 Values:" << std::endl;

	//uint32 values
	for(std::map<std::string,uint32>::iterator i = m_uint32Values.begin();
		i != m_uint32Values.end(); i++) {
			file << "$" << i->first << " = " << i->second << std::endl;
	}
	file << std::endl << "# String Values: " << std::endl;
	for(std::map<std::string,std::string>::iterator i = m_stringValues.begin();
		i != m_stringValues.end(); i++) {
			file << "$" << i->first << " = " << i->second << std::endl;
	}
}

void Settings::SetUint32Value( const std::string& id, uint32 value )
{
	m_uint32Values[id] = value;
}

void Settings::SetStringValue( const std::string& id, const std::string& value )
{
	m_stringValues[id] = value;
}